package behavior;

import arena.Node;
import java.util.Random;

/**
 * RandomBehavior produces a random move continuously for N number
 * of moves.
 *
 * @author      Gabriel Loewen
 */
public class RandomBehavior extends Behavior {

    /**
     * The total number of moves that the robot will take
     */
    private int numMoves = 0;
    /**
     * The number of moves that the robot has taken
     * Note: when count = numMoves the behavior stops
     */
    private int count = 0;
    /**
     * List of possible cardinal directions
     */
    private char[] cardinal = new char[]{'N', 'E', 'S', 'W'};
    /**
     * Random number generator
     */
    private Random generator = new Random();

    /**
     * Default Constructor
     */
    public RandomBehavior() {
        super("Random");
    }

    /**
     * This behavior does not generate a path so there is not path generation
     * progress.
     * @return Always returns 100
     */
    @Override
    public double getProgress() {
        return 100.0;
    }

    /**
     * This behavior does not generate a path so there is not path generation
     * progress.  Unumplemented.
     */
    @Override
    public void resetProgress() {
    }

    /**
     * Gets the user input which represents the number of moves to be
     * taken by the robot.
     *
     * @param   goal    a number from 0 to MAX(Integer) which represents the number of moves.
     * @param   cancel  Not necessary for this behavior
     */
    @Override
    public void getPath(String goal, boolean cancel) {
        
        int moves;

        try {
            moves = (int) Integer.valueOf(goal.trim());
        } catch (NumberFormatException ex) {
            moves = 10;
        }

        this.numMoves = moves;
    }

    /**
     * If the current move count is less than the number of moves than
     * it continues.
     *
     * @return  true if count < numMoves
     */
    @Override
    public boolean hasMove() {
        if (this.count < this.numMoves) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Produces a random integer between 0 and 3 inclusive and uses the
     * integer to choose a cardinal direction.  Then chooses the next node
     * based on the direction and produces the correct output.
     *
     * @return  Standard int array formatted to be read by the robot
     */
    @Override
    public int[] nextMove() {
        int rInt = generator.nextInt(4);

        char direction = this.cardinal[rInt];
        Node nextNode = null;

        switch (direction) {
            case 'N':
                nextNode = robot.getArena().nodeMap.get(robot.getLocation().x + "," +
                        (robot.getLocation().y + 1));
                break;
            case 'S':
                nextNode = robot.getArena().nodeMap.get(robot.getLocation().x + "," +
                        (robot.getLocation().y - 1));
                break;
            case 'E':
                nextNode = robot.getArena().nodeMap.get((robot.getLocation().x + 1) + "," +
                        robot.getLocation().y);
                break;
            case 'W':
                nextNode = robot.getArena().nodeMap.get((robot.getLocation().x - 1) + "," +
                        robot.getLocation().y);
                break;
            default:
                break;
        }

        try {
            if (nextNode != null) {
                if (!nextNode.isOccupied) {
                    count++;
                    return Util.getMoveData(robot.heading, robot.getLocation().x, robot.getLocation().y, direction);
                } else {
                    return nextMove();
                }
            } else {
                return nextMove();
            }
        } catch (Exception ex) {
            return new int[]{'X'};
        }
    }

    /**
     * The move is always valid because the nextMove method insures it
     *
     * @return  true
     */
    @Override
    public boolean isValidMove() {
        return true;
    }
}
